package com.kern.academic.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.kern.academic.bean.ResponseResult;
import com.kern.academic.cache.CacheManager;
import com.kern.academic.cache.constant.RedisCacheKey;
import com.kern.academic.dto.RightsDTO;
import com.kern.academic.dto.RightsGroup;
import com.kern.academic.dto.RightsNode;
import com.kern.academic.entity.XRoleRights;
import com.kern.academic.repository.IRightsRepository;
import com.kern.academic.repository.IRoleRightsResponsitory;
import com.kern.academic.service.IRightsService;
import com.kern.academic.util.CommonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.transaction.Transactional;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Created by caoshi at 7:45 2021-07-13
 */
@Service
public class RightsServiceImpl implements IRightsService {

    private static Logger logger = LoggerFactory.getLogger(RightsServiceImpl.class);

    @Autowired
    private IRightsRepository rightsRepository;

    @Autowired
    private IRoleRightsResponsitory roleRightsResponsitory;

    @Autowired
    private EntityManager entityManager;

    @Autowired
    private CacheManager cacheManager;

    @Override
    public List<RightsDTO> listAll() {
        String sql = "select r.id, r.name, r.desc, r.level, r.code, rg.id as groupId, rg.name as groupName " +
                "from t_rights r left join t_rights_group rg on r.group_id = rg.id";
        Query query = entityManager.createNativeQuery(sql);
        List<?> resultList = query.getResultList();

        List<RightsDTO> rightsDTOList = new ArrayList<>();
        for (Object row : resultList) {
            RightsDTO rdto = new RightsDTO();
            Object[] cells = (Object[]) row;
            if (cells != null) {
                rdto.setId(cells[0] == null ? "" : cells[0].toString());
                rdto.setName(cells[1] == null ? "" : cells[1].toString());
                rdto.setDescription(cells[2] == null ? "" : cells[2].toString());
                rdto.setLevel(cells[3] == null ? 1 : (Integer) cells[3]);
                rdto.setCode(cells[4] == null ? "" : cells[4].toString());
                rdto.setGroupId(cells[5] == null ? "" : cells[5].toString());
                rdto.setGroupName(cells[6] == null ? "" : cells[6].toString());
                rightsDTOList.add(rdto);
            }
        }

        return rightsDTOList;
    }


    /**
     * @param roleId
     * @return
     */
    @Override
    public List<RightsNode> listRightsByRoleId(String roleId) throws IOException, ClassNotFoundException {
        List<RightsNode> rightsNodeList = new ArrayList<>();

        List<String> existIds = listRightsIdsByRoleId(roleId); // 当前角色已有的权限 id
        List<RightsDTO> rightsDTOList = listAll();          // 所有权限
        List<RightsGroup> rightsGroups = listAllGroup();    // 所有权限分组 父级

        // 父级 权限分组
        for (RightsGroup group : rightsGroups) {
            RightsNode pNode = new RightsNode();
            pNode.setId(group.getId());
            pNode.setName(group.getName());
            pNode.setParentId("");
            List<RightsNode> children = new ArrayList<>();
            pNode.setChildren(children);
            rightsNodeList.add(pNode);
        }

        // 装配权限列表
        for (RightsNode node : rightsNodeList) {
            String id = node.getId();
            List<RightsNode> children = node.getChildren();
            for (RightsDTO dto : rightsDTOList) {
                if (Objects.equals(id, dto.getGroupId())) {
                    RightsNode child = new RightsNode();
                    String rightsId = dto.getId();
                    child.setId(rightsId);
                    if (existIds.contains(rightsId)) {
                        child.setExist(true);
                    } else {
                        child.setExist(false);
                    }
                    child.setName(dto.getName());
                    child.setParentId(id);
                    child.setChildren(new ArrayList<>());
                    children.add(child);
                }
            }
        }


        return rightsNodeList;
    }


    @Override
    public List<String> listRightsIdsByRoleId(String roleId) {
        List<XRoleRights> xRoleRights = roleRightsResponsitory.findAllByRoleId(roleId);
        List<String> rightsIds = new ArrayList<>();

        for (XRoleRights xrr : xRoleRights) {
            rightsIds.add(xrr.getRightsId());
        }
        return rightsIds;
    }

    @Override
    public List<RightsGroup> listAllGroup() throws IOException, ClassNotFoundException {
        @SuppressWarnings("unchecked")
        List<RightsGroup> rightsGroups = (List<RightsGroup>) cacheManager.getObject(RedisCacheKey.RIGHTS_GROUPS_KEY);
        if (rightsGroups != null) {
            return rightsGroups;
        } else {
            List<RightsGroup> groups = new ArrayList<>();
            String sql = "select id, name from t_rights_group";
            Query query = entityManager.createNativeQuery(sql);
            List queryResult = query.getResultList();

            for (Object row : queryResult) {
                RightsGroup group = new RightsGroup();
                Object[] item = (Object[]) row;
                String id = item[0] == null ? "" : item[0].toString();
                String name = item[1] == null ? "" : item[1].toString();
                group.setId(id);
                group.setName(name);
                groups.add(group);
            }

            cacheManager.cache(RedisCacheKey.RIGHTS_GROUPS_KEY, groups);
            return groups;
        }
    }

    /**
     *
     * @param roleId
     * @param rightsIdArray  入参 勾选的权限
     * @return
     */
    @Override
    @Transactional
    public ResponseResult authorize(String roleId, JSONArray rightsIdArray) {
        List<String> existIds = listRightsIdsByRoleId(roleId);
        // 要新增的权限
        List<XRoleRights> newRightsList = new ArrayList<>();
        for (int i = 0; i < rightsIdArray.size(); i++) {
            String rid = rightsIdArray.getString(i);
            if (!existIds.contains(rid)) {
                XRoleRights newItem = new XRoleRights();
                newItem.setId(CommonUtil.getUUID());
                newItem.setRoleId(roleId);
                newItem.setRightsId(rid);
                newRightsList.add(newItem);
            }
        }

        // 要删除的权限
        List<String> delRightsIds = new ArrayList<>();
        for (String existId : existIds) {
            if (!rightsIdArray.contains(existId)) {
                delRightsIds.add(existId);
            }
        }

        if (newRightsList.size() == 0 && delRightsIds.size() == 0) {
            return ResponseResult.ok("授权信息未变更!", null);
        }

        // 更新权限信息
        // 1. 先删除取消权限的
        if (delRightsIds.size() > 0) {
            for (String del : delRightsIds) {
                roleRightsResponsitory.deleteByRoleIdAndRightsId(roleId, del);
            }
        }
        // 2. 再新增
        roleRightsResponsitory.saveAll(newRightsList);

        return ResponseResult.ok("授权成功!");
    }

}
